#!/usr/bin/env python
# coding: utf-8

BCM_PORT = 9999
CLI_PORT = 6000
MTN_PORT = 3333
DEV_PORT = 23
ZEBOS_PORT = 2650

import telnetlib
import socket
import re

class tnxxx_portimpbase(object):
    def __init__(self):
        self.__tn = telnetlib.Telnet()
        self._prompt = ''
        self._split_list = []
        self._replace_list = []
        
    def connect(self, ip, slot, port, usr, pwd, timeout):
        rtn = False
        
        try :
            if 0 == slot: #连接OAM
                self.__tn.open(ip, port)
            else: #连接单板
                self.__tn.open(ip, 6264)
                rtn = self.get_tn().read_until(b"examples:nejump 127.0.0.1 23",timeout)
        
                if  rtn.decode().find("examples:nejump 127.0.0.1 23") < 0:
                    return False
        
                cmd = "nejump 192.168.210." + str(slot) + " " + str(port)                
                print(cmd.encode())
                self.get_tn().write(cmd.encode() + b"\n")
       
            rtn = self.login(usr, pwd, timeout)            
        except :
            rtn = False
       
        return rtn
        
    def disconnect(self):
        rtn = False
        try :
            rtn = self.__tn.close()
        except :
            rtn = False
        return rtn

    def send(self, cmd, timeout):
        rtn_all = ''
        
        try :
            rtn = self._send_expect(cmd, self._split_list+[self._prompt], timeout)            
            rtn_all = rtn
            
            while self.find_split(rtn, self._split_list):
                rtn = self._send_expect('', self._split_list+[self._prompt], timeout)
                rtn_all += rtn
            for rep in self._replace_list:
                rtn_all = rtn_all.replace(rep[0], rep[1])
        except :
            pass
        
        return rtn_all

    def send_only(self, cmd, timeout):
        if type(cmd)==str:
            print("cmd:",cmd)   
            cmd = cmd.encode('ascii')
            # print("cmd type encode to : %s" %(type(cmd)))   
        
        try : 
            self.__tn.read_lazy()
            self.__tn.write(cmd+b"\n")
        except :
            return False, ''
        rtn_all = ''
        try :
            rtn = self.__tn.expect(expect_list, timeout)[2]
            rtn_all = rtn
            print("@@@portimpbase:",rtn_all,"@@@")
            while self.find_split(rtn, self._split_list):
                rtn = self._send_expect('', self._split_list+[self._prompt], timeout)
                rtn_all += rtn
            for rep in self._replace_list:
                rtn_all = rtn_all.replace(rep[0], rep[1])
        except :
            pass
        return True, rtn_all
        
    def _send_expect(self, cmd, expect_list, timeout):
        rtn = ''        
        self.__tn.read_lazy()        
        
        if type(cmd)==str:
            # print("cmd:",cmd)
            cmd = cmd.encode('ascii') + b"\n"
            # print("cmd type encode to : %s" %(type(cmd)))        
        
        list=[]
        for expect in expect_list:            
            if type(expect)==str:
                list.append(expect.encode('ascii'))
            else:
                list.append(expect)            
        # print(list)

        self.__tn.write(cmd)        
        rtn = self.__tn.expect(list, timeout)[2]
        rtn += self.__tn.read_very_eager()
        if len(rtn) <= 0:
            print ("Sorry,command operation failed!")
        return rtn.decode()

    def login(self, usr, pwd, timeout):
        return True
    
    def get_tn(self):
        return self.__tn
    
    def get_prompt(self):
        return self._prompt
        
    def find_split(self, rtn, split_list):
        for split in split_list:
            if rtn.find(split) >= 0:
                return True
        return False
    
#-------------------------------------------------------------------------------#
class tnxxx_port_cli(tnxxx_portimpbase):
    def __init__(self):
        tnxxx_portimpbase.__init__(self)
        self._prompt = '#'
        self._split_list = ['--More--']
        # self._replace_list = [('          ','\n')]

    def login(self, usr, pwd, timeout):        
        rtn = self.get_tn().read_until(b"Username:",timeout)        
        if  rtn.decode().find("Username:") < 0:            
            return False
        
        # self.get_tn().write("%s\n"%(usr))
        self.get_tn().write(usr.encode('ascii') + b"\n")
        rtn = self.get_tn().read_until(b"Password:",timeout)      
        
        if  rtn.decode().find("Password:") < 0:
            return False
        
        # self.get_tn().write("%s\n"%(pwd)) 
        self.get_tn().write(pwd.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"#",timeout)
        if  rtn.decode().find("#") < 0:
            return False
        return True
        
    def check_default_rtn(self, cmd, rtn_str):
        #if re.match(r".*?" +cmd + r"[^a-z]*?switch.*",rtn_str) == None:
        if re.match(r".*?" + cmd + r".*?.*", rtn_str, re.S) == None:
            return False
        return True

class tnxxx_port_bcm(tnxxx_portimpbase):
    def __init__(self):
        tnxxx_portimpbase.__init__(self)
        self._prompt = 'BCM.'

    def login(self, usr, pwd, timeout):
        rtn = self.get_tn().read_until(b"login:",timeout)
        if rtn.decode().find("login:") < 0:
            return False
        # self.get_tn().write("%s\n"%(usr))
        self.get_tn().write(usr.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"Password:",timeout)
        if rtn.decode().find("Password:") < 0:
            return False
        # self.get_tn().write("%s\n"%(pwd))
        self.get_tn().write(pwd.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"BCM.",timeout)
        if rtn.decode().find("BCM.") < 0:
            return False
        return True
    
    def check_default_rtn(self, cmd, rtn_str):
        if rtn_str.find("BCM.") < 0 :
            return False
        return True
        
class tnxxx_port_mtn(tnxxx_portimpbase):
    def __init__(self):
        tnxxx_portimpbase.__init__(self)
        self._prompt = '>'

    def login(self, usr, pwd, timeout):
        rtn = self.get_tn().read_until(b"$>",timeout)      
        if  rtn.decode().find("$>") < 0:
            return False
        # self.get_tn().write("%s\n"%(usr))
        self.get_tn().write(usr.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"welcome",timeout)   
        if  rtn.decode().find("welcome") < 0:
            return False
        rtn = self.get_tn().read_until(b"$>",timeout)
        if rtn.decode().find("$>") < 0:
            return False
        return True
        
    def check_default_rtn(self, cmd, rtn_str):
        if rtn_str.find("r - success") < 0:
            return False
        return True
            
class tnxxx_port_dev(tnxxx_portimpbase):
    def __init__(self):
        tnxxx_portimpbase.__init__(self)
        self._prompt = '->'
        self._split_list = ['Type <CR> to continue, Q<CR> to stop']

    def login(self, usr, pwd, timeout):
        rtn = self.get_tn().read_until(b"VxWorks login:",timeout)
        
        if  rtn.decode().find("VxWorks login:") < 0:
            return False
        
        # self.get_tn().write("%s\n"%(usr))
        self.get_tn().write(usr.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"Password:",timeout)      
        if  rtn.decode().find("Password:") < 0:
            return False
        
        # self.get_tn().write("%s\n"%(pwd))
        self.get_tn().write(pwd.encode('ascii') + b"\n") 
        rtn = self.get_tn().read_until(b"->",timeout)
        if  rtn.decode().find("->") < 0:
            return False
        
        return True
    
    def check_default_rtn(self, cmd, rtn_str):
        if rtn_str.find("->") < 0:
            return False
        return True

class tnxxx_port_zebos(tnxxx_portimpbase):
    def __init__(self):
        tnxxx_portimpbase.__init__(self)
        self._prompt = '#'
        self._split_list = ['--More--']
        self._replace_list = [('          ','\n')]

    def login(self, usr, pwd, timeout):
        rtn = self.get_tn().read_until("Password:",timeout)
        if  rtn.find("Password:") < 0:
            return False
        self.get_tn().write("%s\n"%(usr))
        rtn = self.get_tn().read_until("IMI>",timeout)      
        if  rtn.find("IMI>") < 0:
            return False
        self.get_tn().write("%s\n"%(pwd)) 
        rtn = self.get_tn().read_until("IMI#",timeout)
        if  rtn.find("IMI#") < 0:
            return False
        return True
        
    def check_default_rtn(self, cmd, rtn_str):
        #if re.match(r".*?" +cmd + r"[^a-z]*?switch.*",rtn_str) == None:
        if re.match(r".*?" + cmd + r".*?IMI.*", rtn_str, re.S) == None:
            return False
        return True